package de.luh.slimpp.generator

import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.HashMap
import java.util.regex.Pattern

/**
 * A class to resolve header files from types which are not specified as part of the model.
 */
class ExternalHeaderFinder {

	val mapping = new HashMap<String, String>
	val nativeTypes = newLinkedList("void", "bool", "double", "float", "unsigned long", "unsigned int", "unsigned short",
		"unsigned char", "long", "int", "short", "char")

	new(String databaseFile) {
		try {
			val stream = class.getResourceAsStream(databaseFile)
			val reader = new BufferedReader(new InputStreamReader(stream))
			var String line
			while ((line = reader.readLine) != null) {
				val parts = line.split("\t")
				if (parts.size == 2) {
					mapping.put(parts.head, parts.last)
				}
			}
			reader.close()
		} catch (Exception e) {
			e.printStackTrace
		}
	}

	/**
	 * Returns the header file name, already surrounded with <...>, if it is known or null if not.
	 * @param type the type as String where the preceding namespaces are prepended and separated via ::
	 */
	def String findHeader(String type) {
		val header = mapping.get(type)
		if (header != null) {
			return header
		} else {

			// try to fit a regular expression to the list of types and see if one is applicable
			for (item : mapping.keySet) {
				val p = Pattern::compile(item)
				val matcher = p.matcher(type)
				if (matcher.find() && !matcher.find()) {

					// if the matcher finds a first occurrence but no second one
					return mapping.get(item)
				}
			}
			return null
		}
	}

	/**
	 * Returns true if the type is a built-in type and thus needs no header to be used.
	 */
	def needsHeader(String type) {
		!nativeTypes.contains(type)
	}

}
